package wn.lizzy.essay.config;

import java.util.List;
import java.util.Optional;

import javax.annotation.Resource;
import javax.persistence.EntityNotFoundException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;

import wn.lizzy.essay.entity.User;
import wn.lizzy.essay.service.UserService;

// 自定义用户登录校验规则
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

	public static final String CURRENT_USER = "currentUser";

	private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class);

	@Resource
	private UserService userService;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String username = (String) authentication.getPrincipal();
		String password = (String) authentication.getCredentials();
		Optional<User> op = null;
		try {
			op = Optional.ofNullable((User) userService.checkedUser(username, password));
		} catch(EntityNotFoundException e) {
			logger.error("实体未找到", e);
			throw new UsernameNotFoundException(e.getMessage());
		} catch(BadCredentialsException e) {
			logger.error("用户名密码错误", e);
			throw new BadCredentialsException(e.getMessage());
		} catch(LockedException e) {
			logger.error("用户锁定", e);
			throw new LockedException(e.getMessage());
		} catch (Exception e) {
			logger.error("", e);
			throw new AuthenticationServiceException("登录过程中发生未知错误！");
		}

		List<SimpleGrantedAuthority> authorities = Lists.newArrayList();
		UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(op.get(),
				authentication.getCredentials(), authorities);
		result.setDetails(authentication.getDetails());
		return result;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
	}

	public static User getUserInfo() {
		User principal = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		return principal;
	}

}
